import path from 'path'
import esbuild from 'esbuild'
import process from 'process'
import builtins from 'builtin-modules'
import fs from 'fs'

const nodeBuiltins = [...builtins, ...builtins.map((mod) => `node:${mod}`)]

/**
 * Plugin to make pglite's IN_NODE check evaluate to false.
 * pglite checks if it's running in node by evaluating
 * ```ts
 *   typeof process === 'object' &&
 *   typeof process.versions === 'object' &&
 *   typeof process.versions.node === 'string'
 * ```
 * This plugin injects an empty process object at the top of pglite files.
 * 
 * @see https://github.com/electric-sql/pglite/blob/fea963739ccf08ef546265fa3e401bf93f53e81a/packages/pglite/src/utils.ts#L6-L9
 */
const pgliteShimPlugin = {
  name: 'pglite-shim-plugin',
  setup(build) {
    build.onLoad({ filter: /@electric-sql\/pglite/ }, async (args) => {
      const source = await fs.promises.readFile(args.path, 'utf8')
      const shimSource = `const process = {};\n${source}`
      return { contents: shimSource, loader: 'js' }
    })
  },
}


const banner = `/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
`

const prod = process.argv[2] === 'production'

const context = await esbuild.context({
  banner: {
    js: banner,
  },
  entryPoints: ['src/main.ts'],
  bundle: true,
  external: [
    'obsidian',
    'electron',
    '@codemirror/autocomplete',
    '@codemirror/collab',
    '@codemirror/commands',
    '@codemirror/language',
    '@codemirror/lint',
    '@codemirror/search',
    '@codemirror/state',
    '@codemirror/view',
    '@lezer/common',
    '@lezer/highlight',
    '@lezer/lr',
    '@lexical/clipboard/clipboard',
    ...nodeBuiltins,
  ],
  format: 'cjs',
  inject: [path.resolve('import-meta-url-shim.js')],
  define: {
    'import.meta.url': 'import_meta_url',
    'process.env.NODE_ENV': JSON.stringify(prod ? 'production' : 'development'),
  },
  target: 'es2020',
  logLevel: 'info', // 'debug' for more detailed output
  sourcemap: prod ? false : 'inline',
  treeShaking: true,
  outfile: 'main.js',
  minify: prod,
  metafile: true,
  plugins: [pgliteShimPlugin],
})

if (prod) {
  const result = await context.rebuild()
  fs.writeFileSync('meta.json', JSON.stringify(result.metafile))
  process.exit(0)
} else {
  await context.watch()
}
